home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 24 / CU Amiga Magazine's Super CD-ROM 24 (1998)(EMAP Images)(GB)(Track 1 of 2)[!][issue 1998-07].iso / CUCD / Utilities / vim-5.1 / src / eval.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-06  |  57.8 KB  |  2,975 lines

  1. /* vi:set ts=8 sts=4 sw=4:
  2.  *
  3.  * VIM - Vi IMproved    by Bram Moolenaar
  4.  *
  5.  * Do ":help uganda"  in Vim to read copying and usage conditions.
  6.  * Do ":help credits" in Vim to see a list of people who contributed.
  7.  */
  8.  
  9. /*
  10.  * eval.c: Expression evaluation.
  11.  */
  12.  
  13. #include "vim.h"
  14.  
  15. #ifdef HAVE_FCNTL_H
  16. # include <fcntl.h>    /* contains setenv() declaration for Amiga */
  17. #endif
  18. #ifdef AMIGA
  19. # include <time.h>    /* for strftime() */
  20. #endif
  21.  
  22. #ifdef WANT_EVAL
  23.  
  24. typedef struct
  25. {
  26.     char_u    *var_name;    /* name of variable */
  27.     char    var_type;    /* VAR_NUMBER or VAR_STRING */
  28.     union
  29.     {
  30. #if SIZEOF_INT <= 3        /* use long if int is smaller than 32 bits */
  31.     long    var_number;    /* number value */
  32. #else
  33.     int    var_number;    /* number value */
  34. #endif
  35.     char_u    *var_string;    /* string value (Careful: can be NULL!) */
  36.     }        var_val;
  37. } var;
  38.  
  39. #define VAR_UNKNOWN 0
  40. #define VAR_NUMBER  1
  41. #define VAR_STRING  2
  42.  
  43. typedef var *    VAR;
  44.  
  45. /*
  46.  * All user-defined internal variables are stored in variables.
  47.  */
  48. struct growarray    variables;
  49. #define VAR_ENTRY(idx)    (((VAR)(variables.ga_data))[idx])
  50. #define VAR_GAP_ENTRY(idx, gap)    (((VAR)(gap->ga_data))[idx])
  51. #define BVAR_ENTRY(idx)    (((VAR)(curbuf->b_vars.ga_data))[idx])
  52. #define WVAR_ENTRY(idx)    (((VAR)(curwin->w_vars.ga_data))[idx])
  53.  
  54. static int eval0 __ARGS((char_u *arg,  VAR retvar, char_u **nextcmd));
  55. static int eval1 __ARGS((char_u **arg, VAR retvar));
  56. static int eval2 __ARGS((char_u **arg, VAR retvar));
  57. static int eval3 __ARGS((char_u **arg, VAR retvar));
  58. static int eval4 __ARGS((char_u **arg, VAR retvar));
  59. static int eval5 __ARGS((char_u **arg, VAR retvar));
  60. static int eval6 __ARGS((char_u **arg, VAR retvar));
  61. static int get_option_var __ARGS((char_u **arg, VAR retvar));
  62. static int get_string_var __ARGS((char_u **arg, VAR retvar));
  63. static int get_lit_string_var __ARGS((char_u **arg, VAR retvar));
  64. static int get_env_var __ARGS((char_u **arg, VAR retvar));
  65. static int get_func_var __ARGS((char_u *name, int len, VAR retvar, char_u **arg));
  66. static void f_buffer_exists __ARGS((VAR argvars, VAR retvar));
  67. static BUF *get_buf_var __ARGS((VAR avar));
  68. static void f_buffer_name __ARGS((VAR argvars, VAR retvar));
  69. static void f_buffer_number __ARGS((VAR argvars, VAR retvar));
  70. static void f_char2nr __ARGS((VAR argvars, VAR retvar));
  71. static void f_col __ARGS((VAR argvars, VAR retvar));
  72. static void f_delete __ARGS((VAR argvars, VAR retvar));
  73. static void f_exists __ARGS((VAR argvars, VAR retvar));
  74. static void f_expand __ARGS((VAR argvars, VAR retvar));
  75. static void f_file_readable __ARGS((VAR argvars, VAR retvar));
  76. static void f_getcwd __ARGS((VAR argvars, VAR retvar));
  77. static void f_getline __ARGS((VAR argvars, VAR retvar));
  78. static void f_has __ARGS((VAR argvars, VAR retvar));
  79. static void f_highlight_exists __ARGS((VAR argvars, VAR retvar));
  80. static void f_highlightID __ARGS((VAR argvars, VAR retvar));
  81. static void f_hostname __ARGS((VAR argvars, VAR retvar));
  82. static void f_isdirectory __ARGS((VAR argvars, VAR retvar));
  83. static void f_last_buffer_nr __ARGS((VAR argvars, VAR retvar));
  84. static void f_line __ARGS((VAR argvars, VAR retvar));
  85. static void f_match __ARGS((VAR argvars, VAR retvar));
  86. static void f_matchend __ARGS((VAR argvars, VAR retvar));
  87. static void f_nr2char __ARGS((VAR argvars, VAR retvar));
  88. static void f_some_match __ARGS((VAR argvars, VAR retvar, int start));
  89. static void f_strftime __ARGS((VAR argvars, VAR retvar));
  90. static void f_strlen __ARGS((VAR argvars, VAR retvar));
  91. static void f_strpart __ARGS((VAR argvars, VAR retvar));
  92. static void f_synID __ARGS((VAR argvars, VAR retvar));
  93. static void f_synIDattr __ARGS((VAR argvars, VAR retvar));
  94. static void f_synIDtrans __ARGS((VAR argvars, VAR retvar));
  95. static void f_substitute __ARGS((VAR argvars, VAR retvar));
  96. static void f_tempname __ARGS((VAR argvars, VAR retvar));
  97. static void f_virtcol __ARGS((VAR argvars, VAR retvar));
  98. static void f_winheight __ARGS((VAR argvars, VAR retvar));
  99. static FPOS *var2fpos __ARGS((VAR varp));
  100. static int get_env_len __ARGS((char_u **arg));
  101. char_u *get_env_string __ARGS((char_u **arg));
  102. static int get_id_len __ARGS((char_u **arg));
  103. static int eval_isnamec __ARGS((int c));
  104. static int get_var_var __ARGS((char_u *name, int len, VAR retvar));
  105. static VAR alloc_var __ARGS((void));
  106. static VAR alloc_string_var __ARGS((char_u *string));
  107. static void free_var __ARGS((VAR varp));
  108. static void clear_var __ARGS((VAR varp));
  109. static long get_var_number __ARGS((VAR varp));
  110. static char_u *get_var_string __ARGS((VAR varp));
  111. static char_u *get_var_string_buf __ARGS((VAR varp, char_u *buf));
  112. static VAR find_var __ARGS((char_u *name));
  113. static struct growarray *find_var_ga __ARGS((char_u *name, char_u **varname));
  114. static void var_free_one __ARGS((VAR v));
  115. static void list_one_var __ARGS((VAR v, char_u *prefix));
  116. static void set_var __ARGS((char_u *name, VAR varp));
  117. static char_u *find_option_end __ARGS((char_u *p));
  118.  
  119. /*
  120.  * Set an internal variable to a string value. Creates the variable if it does
  121.  * not already exist.
  122.  */
  123.     void
  124. set_internal_string_var(name, value)
  125.     char_u    *name;
  126.     char_u    *value;
  127. {
  128.     char_u  *val;
  129.     VAR        varp;
  130.  
  131.     val = vim_strsave(value);
  132.     if (val != NULL)
  133.     {
  134.     varp = alloc_string_var(val);
  135.     if (varp != NULL)
  136.     {
  137.         set_var(name, varp);
  138.         free_var(varp);
  139.     }
  140.     }
  141. }
  142.  
  143. /*
  144.  * Top level evaluation function, returning a boolean.
  145.  * Sets "error" to TRUE if there was an error.
  146.  * Return TRUE or FALSE.
  147.  */
  148.     int
  149. eval_to_bool(arg, error, nextcmd)
  150.     char_u    *arg;
  151.     int        *error;
  152.     char_u    **nextcmd;
  153. {
  154.     var        retvar;
  155.     int        retval;
  156.  
  157.     if (eval0(arg, &retvar, nextcmd) == FAIL)
  158.     {
  159.     *error = TRUE;
  160.     retval = FALSE;
  161.     }
  162.     else
  163.     {
  164.     *error = FALSE;
  165.     retval = (get_var_number(&retvar) != 0);
  166.     clear_var(&retvar);
  167.     }
  168.  
  169.     return retval;
  170. }
  171.  
  172. /*
  173.  * Top level evaluation function, returning a string.
  174.  * Return pointer to allocated memory, or NULL for failure.
  175.  */
  176.     char_u *
  177. eval_to_string(arg, nextcmd)
  178.     char_u    *arg;
  179.     char_u    **nextcmd;
  180. {
  181.     var        retvar;
  182.     char_u    *retval;
  183.  
  184.     if (eval0(arg, &retvar, nextcmd) == FAIL)
  185.     retval = NULL;
  186.     else
  187.     {
  188.     retval = vim_strsave(get_var_string(&retvar));
  189.     clear_var(&retvar);
  190.     }
  191.  
  192.     return retval;
  193. }
  194.  
  195. /*
  196.  * ":let var = expr"    assignment command.
  197.  * ":let var"        list one variable value
  198.  * ":let"        list all variable values
  199.  */
  200.     void
  201. do_let(eap)
  202.     EXARG    *eap;
  203. {
  204.     char_u    *arg = eap->arg;
  205.     char_u    *expr;
  206.     char_u    *name;
  207.     VAR        varp;
  208.     var        retvar;
  209.     char_u    *p;
  210.     int        c1, c2;
  211.     int        i;
  212. #ifndef HAVE_SETENV
  213.     char_u    *envbuf;
  214. #endif
  215.  
  216.     expr = vim_strchr(arg, '=');
  217.     if (expr == NULL)
  218.     {
  219.     if (ends_excmd(*arg))
  220.     {
  221.         if (!eap->skip)
  222.         {
  223.         /*
  224.          * List all variables.
  225.          */
  226.         for (i = 0; i < variables.ga_len; ++i)
  227.             if (VAR_ENTRY(i).var_name != NULL)
  228.             list_one_var(&VAR_ENTRY(i), (char_u *)"");
  229.         for (i = 0; i < curbuf->b_vars.ga_len; ++i)
  230.             if (BVAR_ENTRY(i).var_name != NULL)
  231.             list_one_var(&BVAR_ENTRY(i), (char_u *)"b:");
  232.         for (i = 0; i < curwin->w_vars.ga_len; ++i)
  233.             if (WVAR_ENTRY(i).var_name != NULL)
  234.             list_one_var(&WVAR_ENTRY(i), (char_u *)"w:");
  235.         }
  236.     }
  237.     else
  238.     {
  239.         /*
  240.          * List variables.
  241.          */
  242.         while (!ends_excmd(*arg))
  243.         {
  244.         for (p = arg; eval_isnamec(*p); ++p)
  245.             ;
  246.         if (!vim_iswhite(*p) && !ends_excmd(*p))
  247.         {
  248.             EMSG(e_trailing);
  249.             break;
  250.         }
  251.         if (!eap->skip)
  252.         {
  253.             c1 = *p;
  254.             *p = NUL;
  255.             varp = find_var(arg);
  256.             if (varp == NULL)
  257.             EMSG2("Unknown variable: \"%s\"", arg);
  258.             else
  259.             {
  260.             name = vim_strchr(arg, ':');
  261.             if (name != NULL)
  262.             {
  263.                 c2 = *++name;
  264.                 *name = NUL;
  265.                 list_one_var(varp, arg);
  266.                 *name = c2;
  267.             }
  268.             else
  269.                 list_one_var(varp, (char_u *)"");
  270.             }
  271.             *p = c1;
  272.         }
  273.         arg = skipwhite(p);
  274.         }
  275.     }
  276.     eap->nextcmd = check_nextcmd(arg);
  277.     }
  278.     else
  279.     {
  280.     if (eap->skip)
  281.         ++emsg_off;
  282.     i = eval0(expr + 1, &retvar, &eap->nextcmd);
  283.     if (eap->skip)
  284.         --emsg_off;
  285.     else if (i != FAIL)
  286.     {
  287.         /*
  288.          * ":let $VAR = expr": Set environment variable.
  289.          */
  290.         if (*arg == '$')
  291.         {
  292.         int    len;
  293.         int    cc;
  294.  
  295.         /* Find the end of the name. */
  296.         ++arg;
  297.         name = arg;
  298.         len = get_env_len(&arg);
  299.         if (name != NULL)
  300.         {
  301.             if (*skipwhite(arg) != '=')
  302.             EMSG(e_letunexp);
  303.             else
  304.             {
  305.             cc = name[len];
  306.             name[len] = NUL;
  307.             p = get_var_string(&retvar);
  308. #ifdef HAVE_SETENV
  309. # if defined(AMIGA) || defined(VMS)
  310.             vim_setenv((char *)name, (char *)p);
  311. # else
  312.             setenv((char *)name, (char *)p, 1);
  313. # endif
  314. #else
  315.             /*
  316.              * Putenv does not copy the string, it has to remain
  317.              * valid.  The allocated memory will never be freed.
  318.              */
  319.             envbuf = alloc((unsigned)(STRLEN(p) +
  320.                                STRLEN(name) + 2));
  321.             if (envbuf != NULL)
  322.             {
  323.                 sprintf((char *)envbuf, "%s=%s", name, p);
  324.                 putenv((char *)envbuf);
  325.             }
  326. #endif
  327.             if (STRICMP(name, "home") == 0)
  328.                 init_homedir();
  329.             name[len] = cc;
  330.             }
  331.         }
  332.         }
  333.  
  334.         /*
  335.          * ":let &option = expr": Set option value.
  336.          */
  337.         else if (*arg == '&')
  338.         {
  339.         /*
  340.          * Find the end of the name;
  341.          */
  342.         ++arg;
  343.         p = find_option_end(arg);
  344.         if (*skipwhite(p) != '=')
  345.             EMSG(e_letunexp);
  346.         else
  347.         {
  348.             c1 = *p;
  349.             *p = NUL;
  350.             set_option_value(arg, get_var_number(&retvar),
  351.                              get_var_string(&retvar));
  352.             *p = c1;            /* put back for error messages */
  353.         }
  354.         }
  355.  
  356.         /*
  357.          * ":let @r = expr": Set register contents.
  358.          */
  359.         else if (*arg == '@')
  360.         {
  361.         ++arg;
  362.         if (*skipwhite(arg + 1) != '=')
  363.             EMSG(e_letunexp);
  364.         else
  365.             write_reg_contents(*arg == '@' ? '"' : *arg,
  366.                              get_var_string(&retvar));
  367.         }
  368.  
  369.         /*
  370.          * ":let var = expr": Set internal variable.
  371.          */
  372.         else if (eval_isnamec(*arg) && !isdigit(*arg))
  373.         {
  374.         /*
  375.          * Find the end of the name;
  376.          */
  377.         for (p = arg; eval_isnamec(*p); ++p)
  378.             ;
  379.         if (*skipwhite(p) != '=')
  380.             EMSG(e_letunexp);
  381.         else
  382.         {
  383.             c1 = *p;
  384.             *p = NUL;
  385.             set_var(arg, &retvar);
  386.             *p = c1;        /* put char back for error messages */
  387.         }
  388.         }
  389.  
  390.         else
  391.         {
  392.         EMSG2(e_invarg2, arg);
  393.         }
  394.  
  395.     }
  396.     clear_var(&retvar);
  397.     }
  398. }
  399.  
  400. /*
  401.  * ":unlet var" command.
  402.  */
  403.     void
  404. do_unlet(arg)
  405.     char_u    *arg;
  406. {
  407.     char_u        *name_end;
  408.     VAR            v;
  409.     int            cc;
  410.  
  411.     name_end = skiptowhite(arg);
  412.     cc = *name_end;
  413.     *name_end = NUL;
  414.  
  415.     v = find_var(arg);
  416.     if (v != NULL)        /* existing variable, may need to free string */
  417.     var_free_one(v);
  418.     else            /* non-existing variable */
  419.     EMSG2("No such variable: \"%s\"", arg);
  420.  
  421.     *name_end = cc;
  422. }
  423.  
  424. /*
  425.  * types for expressions.
  426.  */
  427. enum exp_type
  428. {
  429.     TYPE_UNKNOWN = 0,
  430.     TYPE_EQUAL,        /* == */
  431.     TYPE_NEQUAL,    /* != */
  432.     TYPE_GREATER,    /* >  */
  433.     TYPE_GEQUAL,    /* >= */
  434.     TYPE_SMALLER,    /* <  */
  435.     TYPE_SEQUAL,    /* <= */
  436.     TYPE_MATCH,        /* =~ */
  437.     TYPE_NOMATCH    /* !~ */
  438. };
  439.  
  440. /*
  441.  * Handle zero level expression.
  442.  * This calls eval1() and handles error message and nextcmd.
  443.  * Return OK or FAIL.
  444.  */
  445.     static int
  446. eval0(arg, retvar, nextcmd)
  447.     char_u    *arg;
  448.     VAR        retvar;
  449.     char_u    **nextcmd;
  450. {
  451.     int        ret = OK;
  452.     char_u    *p;
  453.  
  454.     p = skipwhite(arg);
  455.     if (eval1(&p, retvar) == FAIL || !ends_excmd(*p))
  456.     {
  457.     EMSG2(e_invexpr2, arg);
  458.     ret = FAIL;
  459.     }
  460.     if (nextcmd != NULL)
  461.     *nextcmd = check_nextcmd(p);
  462.  
  463.     return ret;
  464. }
  465.  
  466. /*
  467.  * Handle first level expression:
  468.  *    expr2 || expr2 || expr2        logical OR
  469.  *
  470.  * "arg" must point to the first non-white of the expression.
  471.  * "arg" is advanced to the next non-white after the recognized expression.
  472.  *
  473.  * Return OK or FAIL.
  474.  */
  475.     static int
  476. eval1(arg, retvar)
  477.     char_u    **arg;
  478.     VAR        retvar;
  479. {
  480.     var        var2;
  481.     long    n1, n2;
  482.  
  483.     /*
  484.      * Get the first variable.
  485.      */
  486.     if (eval2(arg, retvar) == FAIL)
  487.     return FAIL;
  488.  
  489.     /*
  490.      * Repeat until there is no following "||".
  491.      */
  492.     while ((*arg)[0] == '|' && (*arg)[1] == '|')
  493.     {
  494.     n1 = get_var_number(retvar);
  495.     clear_var(retvar);
  496.  
  497.     /*
  498.      * Get the second variable.
  499.      */
  500.     *arg = skipwhite(*arg + 2);
  501.     if (eval2(arg, &var2) == FAIL)
  502.         return FAIL;
  503.  
  504.     /*
  505.      * Compute the result.
  506.      */
  507.     n2 = get_var_number(&var2);
  508.     clear_var(&var2);
  509.     retvar->var_type = VAR_NUMBER;
  510.     retvar->var_val.var_number = (n1 || n2);
  511.     }
  512.  
  513.     return OK;
  514. }
  515.  
  516. /*
  517.  * Handle second level expression:
  518.  *    expr3 && expr3 && expr3        logical AND
  519.  *
  520.  * "arg" must point to the first non-white of the expression.
  521.  * "arg" is advanced to the next non-white after the recognized expression.
  522.  *
  523.  * Return OK or FAIL.
  524.  */
  525.     static int
  526. eval2(arg, retvar)
  527.     char_u    **arg;
  528.     VAR        retvar;
  529. {
  530.     var        var2;
  531.     long    n1, n2;
  532.  
  533.     /*
  534.      * Get the first variable.
  535.      */
  536.     if (eval3(arg, retvar) == FAIL)
  537.     return FAIL;
  538.  
  539.     /*
  540.      * Repeat until there is no following "&&".
  541.      */
  542.     while ((*arg)[0] == '&' && (*arg)[1] == '&')
  543.     {
  544.     n1 = get_var_number(retvar);
  545.     clear_var(retvar);
  546.  
  547.     /*
  548.      * Get the second variable.
  549.      */
  550.     *arg = skipwhite(*arg + 2);
  551.     if (eval3(arg, &var2) == FAIL)
  552.         return FAIL;
  553.  
  554.     /*
  555.      * Compute the result.
  556.      */
  557.     n2 = get_var_number(&var2);
  558.     clear_var(&var2);
  559.     retvar->var_type = VAR_NUMBER;
  560.     retvar->var_val.var_number = (n1 && n2);
  561.     }
  562.  
  563.     return OK;
  564. }
  565.  
  566. /*
  567.  * Handle third level expression:
  568.  *    var1 == var2
  569.  *    var1 =~ var2
  570.  *    var1 != var2
  571.  *    var1 !~ var2
  572.  *    var1 > var2
  573.  *    var1 >= var2
  574.  *    var1 < var2
  575.  *    var1 <= var2
  576.  *
  577.  * "arg" must point to the first non-white of the expression.
  578.  * "arg" is advanced to the next non-white after the recognized expression.
  579.  *
  580.  * Return OK or FAIL.
  581.  */
  582.     static int
  583. eval3(arg, retvar)
  584.     char_u    **arg;
  585.     VAR        retvar;
  586. {
  587.     var            var2;
  588.     char_u        *p;
  589.     int            i = 0;
  590.     enum exp_type    type = TYPE_UNKNOWN;
  591.     int            len = 2;
  592.     long        n1 = FALSE, n2;
  593.     char_u        *s1, *s2;
  594.     char_u        buf1[NUMBUFLEN], buf2[NUMBUFLEN];
  595.     vim_regexp        *prog;
  596.  
  597.     /*
  598.      * Get the first variable.
  599.      */
  600.     if (eval4(arg, retvar) == FAIL)
  601.     return FAIL;
  602.  
  603.     p = *arg;
  604.     switch (p[0])
  605.     {
  606.     case '=':   if (p[1] == '=')
  607.             type = TYPE_EQUAL;
  608.             else if (p[1] == '~')
  609.             type = TYPE_MATCH;
  610.             break;
  611.     case '!':   if (p[1] == '=')
  612.             type = TYPE_NEQUAL;
  613.             else if (p[1] == '~')
  614.             type = TYPE_NOMATCH;
  615.             break;
  616.     case '>':   if (p[1] != '=')
  617.             {
  618.             type = TYPE_GREATER;
  619.             len = 1;
  620.             }
  621.             else
  622.             type = TYPE_GEQUAL;
  623.             break;
  624.     case '<':   if (p[1] != '=')
  625.             {
  626.             type = TYPE_SMALLER;
  627.             len = 1;
  628.             }
  629.             else
  630.             type = TYPE_SEQUAL;
  631.             break;
  632.     }
  633.  
  634.     /*
  635.      * If there is a comparitive operator, use it.
  636.      */
  637.     if (type != TYPE_UNKNOWN)
  638.     {
  639.     /*
  640.      * Get the second variable.
  641.      */
  642.     *arg = skipwhite(p + len);
  643.     if (eval4(arg, &var2) == FAIL)
  644.     {
  645.         clear_var(retvar);
  646.         return FAIL;
  647.     }
  648.  
  649.     /*
  650.      * If one of the two variables is a number, compare as a number.
  651.      * When using "=~" or "!~", always compare as string.
  652.      */
  653.     if ((retvar->var_type == VAR_NUMBER || var2.var_type == VAR_NUMBER)
  654.         && type != TYPE_MATCH && type != TYPE_NOMATCH)
  655.     {
  656.         n1 = get_var_number(retvar);
  657.         n2 = get_var_number(&var2);
  658.         switch (type)
  659.         {
  660.         case TYPE_EQUAL:    n1 = (n1 == n2); break;
  661.         case TYPE_NEQUAL:   n1 = (n1 != n2); break;
  662.         case TYPE_GREATER:  n1 = (n1 > n2); break;
  663.         case TYPE_GEQUAL:   n1 = (n1 >= n2); break;
  664.         case TYPE_SMALLER:  n1 = (n1 < n2); break;
  665.         case TYPE_SEQUAL:   n1 = (n1 <= n2); break;
  666.         case TYPE_UNKNOWN:
  667.         case TYPE_MATCH:
  668.         case TYPE_NOMATCH:  break;  /* avoid gcc warning */
  669.         }
  670.     }
  671.     else
  672.     {
  673.         s1 = get_var_string_buf(retvar, buf1);
  674.         s2 = get_var_string_buf(&var2, buf2);
  675.         if (type != TYPE_MATCH && type != TYPE_NOMATCH)
  676.         i = STRCMP(s1, s2);
  677.         switch (type)
  678.         {
  679.         case TYPE_EQUAL:    n1 = (i == 0); break;
  680.         case TYPE_NEQUAL:   n1 = (i != 0); break;
  681.         case TYPE_GREATER:  n1 = (i > 0); break;
  682.         case TYPE_GEQUAL:   n1 = (i >= 0); break;
  683.         case TYPE_SMALLER:  n1 = (i < 0); break;
  684.         case TYPE_SEQUAL:   n1 = (i <= 0); break;
  685.         case TYPE_MATCH:
  686.         case TYPE_NOMATCH:  reg_ic = p_ic;
  687.                     prog = vim_regcomp(s2, TRUE);
  688.                     if (prog != NULL)
  689.                     {
  690.                     n1 = vim_regexec(prog, s1, TRUE);
  691.                     vim_free(prog);
  692.                     if (type == TYPE_NOMATCH)
  693.                         n1 = !n1;
  694.                     }
  695.                     break;
  696.         case TYPE_UNKNOWN:  break;  /* avoid gcc warning */
  697.         }
  698.     }
  699.     clear_var(retvar);
  700.     clear_var(&var2);
  701.     retvar->var_type = VAR_NUMBER;
  702.     retvar->var_val.var_number = n1;
  703.     }
  704.  
  705.     return OK;
  706. }
  707.  
  708. /*
  709.  * Handle fourth level expression:
  710.  *    +    number addition
  711.  *    -    number subtraction
  712.  *    .    string concatenation
  713.  *
  714.  * "arg" must point to the first non-white of the expression.
  715.  * "arg" is advanced to the next non-white after the recognized expression.
  716.  *
  717.  * Return OK or FAIL.
  718.  */
  719.     static int
  720. eval4(arg, retvar)
  721.     char_u    **arg;
  722.     VAR        retvar;
  723. {
  724.     var        var2;
  725.     int        op;
  726.     long    n1, n2;
  727.     char_u    *s1, *s2;
  728.     char_u    buf1[NUMBUFLEN], buf2[NUMBUFLEN];
  729.     char_u    *p;
  730.  
  731.     /*
  732.      * Get the first variable.
  733.      */
  734.     if (eval5(arg, retvar) == FAIL)
  735.     return FAIL;
  736.  
  737.     /*
  738.      * Repeat computing, until no '+', '-' or '.' is following.
  739.      */
  740.     for (;;)
  741.     {
  742.     op = **arg;
  743.     if (op != '+' && op != '-' && op != '.')
  744.         break;
  745.  
  746.     /*
  747.      * Get the second variable.
  748.      */
  749.     *arg = skipwhite(*arg + 1);
  750.     if (eval5(arg, &var2) == FAIL)
  751.     {
  752.         clear_var(retvar);
  753.         return FAIL;
  754.     }
  755.  
  756.     /*
  757.      * Compute the result.
  758.      */
  759.     if (op == '.')
  760.     {
  761.         s1 = get_var_string_buf(retvar, buf1);
  762.         s2 = get_var_string_buf(&var2, buf2);
  763.         p = alloc((unsigned)(STRLEN(s1) + STRLEN(s2) + 1));
  764.         if (p != NULL)
  765.         {
  766.         STRCPY(p, s1);
  767.         STRCAT(p, s2);
  768.         }
  769.         clear_var(retvar);
  770.         retvar->var_type = VAR_STRING;
  771.         retvar->var_val.var_string = p;
  772.     }
  773.     else
  774.     {
  775.         n1 = get_var_number(retvar);
  776.         n2 = get_var_number(&var2);
  777.         clear_var(retvar);
  778.         if (op == '+')
  779.         n1 = n1 + n2;
  780.         else
  781.         n1 = n1 - n2;
  782.         retvar->var_type = VAR_NUMBER;
  783.         retvar->var_val.var_number = n1;
  784.     }
  785.     clear_var(&var2);
  786.     }
  787.     return OK;
  788. }
  789.  
  790. /*
  791.  * Handle fifth level expression:
  792.  *    *    number multiplication
  793.  *    /    number division
  794.  *    %    number modulo
  795.  *
  796.  * "arg" must point to the first non-white of the expression.
  797.  * "arg" is advanced to the next non-white after the recognized expression.
  798.  *
  799.  * Return OK or FAIL.
  800.  */
  801.     static int
  802. eval5(arg, retvar)
  803.     char_u    **arg;
  804.     VAR        retvar;
  805. {
  806.     var        var2;
  807.     int        op;
  808.     long    n1, n2;
  809.  
  810.     /*
  811.      * Get the first variable.
  812.      */
  813.     if (eval6(arg, retvar) == FAIL)
  814.     return FAIL;
  815.  
  816.     /*
  817.      * Repeat computing, until no '*', '/' or '%' is following.
  818.      */
  819.     for (;;)
  820.     {
  821.     op = **arg;
  822.     if (op != '*' && op != '/' && op != '%')
  823.         break;
  824.  
  825.     n1 = get_var_number(retvar);
  826.     clear_var(retvar);
  827.  
  828.     /*
  829.      * Get the second variable.
  830.      */
  831.     *arg = skipwhite(*arg + 1);
  832.     if (eval6(arg, &var2) == FAIL)
  833.         return FAIL;
  834.     n2 = get_var_number(&var2);
  835.     clear_var(&var2);
  836.  
  837.     /*
  838.      * Compute the result.
  839.      */
  840.     if (op == '*')
  841.         n1 = n1 * n2;
  842.     else if (op == '/')
  843.     {
  844.         if (n2 == 0)    /* give an error message? */
  845.         n1 = 0x7fffffff;
  846.         else
  847.         n1 = n1 / n2;
  848.     }
  849.     else
  850.     {
  851.         if (n2 == 0)    /* give an error message? */
  852.         n1 = 0;
  853.         else
  854.         n1 = n1 % n2;
  855.     }
  856.     retvar->var_type = VAR_NUMBER;
  857.     retvar->var_val.var_number = n1;
  858.     }
  859.  
  860.     return OK;
  861. }
  862.  
  863. /*
  864.  * Handle sixth level expression:
  865.  *  number        number constant
  866.  *  "string"        string contstant
  867.  *  *option-name    option value
  868.  *  @r            register contents
  869.  *  identifier        variable value
  870.  *  $VAR        environment variable
  871.  *  (expression)    nested expression
  872.  *
  873.  *  Also handle:
  874.  *  ! in front        logical NOT
  875.  *  - in front        unary minus
  876.  *  trailing []        subscript in String
  877.  *
  878.  * "arg" must point to the first non-white of the expression.
  879.  * "arg" is advanced to the next non-white after the recognized expression.
  880.  *
  881.  * Return OK or FAIL.
  882.  */
  883.     static int
  884. eval6(arg, retvar)
  885.     char_u    **arg;
  886.     VAR        retvar;
  887. {
  888.     var        var2;
  889.     long    n;
  890.     int        len;
  891.     char_u    *s;
  892.     int        val;
  893.     char_u    *start_leader, *end_leader;
  894.     int        ret = OK;
  895.  
  896.     /*
  897.      * Skip '!' and '-' characters.  They are handled later.
  898.      */
  899.     start_leader = *arg;
  900.     while (**arg == '!' || **arg == '-')
  901.     *arg = skipwhite(*arg + 1);
  902.     end_leader = *arg;
  903.  
  904.     switch (**arg)
  905.     {
  906.     /*
  907.      * Number constant.
  908.      */
  909.     case '0':
  910.     case '1':
  911.     case '2':
  912.     case '3':
  913.     case '4':
  914.     case '5':
  915.     case '6':
  916.     case '7':
  917.     case '8':
  918.     case '9':
  919.         retvar->var_type = VAR_NUMBER;
  920.         retvar->var_val.var_number =
  921.                      vim_str2nr(*arg, NULL, &len, TRUE, TRUE);
  922.         *arg += len;
  923.         break;
  924.  
  925.     /*
  926.      * String constant: "string".
  927.      */
  928.     case '\"':    ret = get_string_var(arg, retvar);
  929.         break;
  930.  
  931.     /*
  932.      * Literal string constant: 'string'.
  933.      */
  934.     case '\'':    ret = get_lit_string_var(arg, retvar);
  935.         break;
  936.  
  937.     /*
  938.      * Option value: &name
  939.      */
  940.     case '&':    ret = get_option_var(arg, retvar);
  941.         break;
  942.  
  943.     /*
  944.      * Environment variable: $VAR.
  945.      */
  946.     case '$':    ret = get_env_var(arg, retvar);
  947.         break;
  948.  
  949.     /*
  950.      * Register contents: @r.
  951.      */
  952.     case '@':    retvar->var_type = VAR_STRING;
  953.         retvar->var_val.var_string = get_reg_contents(*++*arg);
  954.         if (**arg != NUL)
  955.             ++*arg;
  956.         break;
  957.  
  958.     /*
  959.      * nested expression: (expression).
  960.      */
  961.     case '(':    *arg = skipwhite(*arg + 1);
  962.         ret = eval1(arg, retvar);    /* recursive! */
  963.         if (**arg != ')')
  964.             EMSG("Missing ')'");
  965.         else
  966.             ++*arg;
  967.         break;
  968.  
  969.     /*
  970.      * Must be a variable or function name then.
  971.      */
  972.     default:    s = *arg;
  973.         len = get_id_len(arg);
  974.         if (len)
  975.         {
  976.             if (**arg == '(')        /* recursive! */
  977.             ret = get_func_var(s, len, retvar, arg);
  978.             else
  979.             ret = get_var_var(s, len, retvar);
  980.         }
  981.         else
  982.             ret = FAIL;
  983.         break;
  984.     }
  985.     *arg = skipwhite(*arg);
  986.  
  987.     /*
  988.      * Handle expr[expr] subscript.
  989.      */
  990.     if (**arg == '[' && ret == OK)
  991.     {
  992.     /*
  993.      * Get the variable from inside the [].
  994.      */
  995.     *arg = skipwhite(*arg + 1);
  996.     if (eval1(arg, &var2) == FAIL)        /* recursive! */
  997.     {
  998.         clear_var(retvar);
  999.         return FAIL;
  1000.     }
  1001.     n = get_var_number(&var2);
  1002.  
  1003.     /* Check for the ']'. */
  1004.     if (**arg != ']')
  1005.     {
  1006.         EMSG("Missing ']'");
  1007.         clear_var(retvar);
  1008.         return FAIL;
  1009.     }
  1010.  
  1011.     /*
  1012.      * The resulting variable is a string of a single character.
  1013.      * If the index is too big or negative, the result is empty.
  1014.      */
  1015.     s = get_var_string(retvar);
  1016.     if (n >= (long)STRLEN(s) || n < 0)
  1017.         s = NULL;
  1018.     else
  1019.         s = vim_strnsave(s + n, 1);
  1020.     clear_var(retvar);
  1021.     retvar->var_type = VAR_STRING;
  1022.     retvar->var_val.var_string = s;
  1023.  
  1024.     *arg = skipwhite(*arg + 1);    /* skip the ']' */
  1025.     }
  1026.  
  1027.     /*
  1028.      * Apply logical NOT and unary '-', from right to left.
  1029.      */
  1030.     if (ret == OK && end_leader > start_leader)
  1031.     {
  1032.     val = get_var_number(retvar);
  1033.     while (end_leader > start_leader)
  1034.     {
  1035.         --end_leader;
  1036.         if (*end_leader == '!')
  1037.         val = !val;
  1038.         else if (*end_leader == '-')
  1039.         val = -val;
  1040.     }
  1041.     clear_var(retvar);
  1042.     retvar->var_type = VAR_NUMBER;
  1043.     retvar->var_val.var_number = val;
  1044.     }
  1045.  
  1046.     return ret;
  1047. }
  1048.  
  1049. /*
  1050.  * Get an option value.
  1051.  * "arg" points to the '&' before the option name.
  1052.  * "arg" is advanced to character after the option name.
  1053.  * Return OK or FAIL.
  1054.  */
  1055.     static int
  1056. get_option_var(arg, retvar)
  1057.     char_u    **arg;
  1058.     VAR        retvar;        /* when NULL, only check if option exists */
  1059. {
  1060.     char_u    *option_end;
  1061.     long    numval;
  1062.     char_u    *stringval;
  1063.     int        opt_type;
  1064.     int        c;
  1065.     int        ret = OK;
  1066.  
  1067.     /*
  1068.      * Isolate the option name and find its value.
  1069.      */
  1070.     option_end = find_option_end(*arg + 1);
  1071.     if (option_end == *arg + 1)
  1072.     {
  1073.     if (retvar != NULL)
  1074.         EMSG2("Option name missing: %s", *arg);
  1075.     return FAIL;
  1076.     }
  1077.  
  1078.     c = *option_end;
  1079.     *option_end = NUL;
  1080.     opt_type = get_option_value(*arg + 1, &numval,
  1081.                       retvar == NULL ? NULL : &stringval);
  1082.  
  1083.     if (opt_type < 0)            /* invalid name */
  1084.     {
  1085.     if (retvar != NULL)
  1086.         EMSG2("Unknown option: %s", *arg + 1);
  1087.     ret = FAIL;
  1088.     }
  1089.     else if (retvar != NULL)
  1090.     {
  1091.     if (opt_type == 1)        /* number option */
  1092.     {
  1093.         retvar->var_type = VAR_NUMBER;
  1094.         retvar->var_val.var_number = numval;
  1095.     }
  1096.     else                /* string option */
  1097.     {
  1098.         retvar->var_type = VAR_STRING;
  1099.         retvar->var_val.var_string = stringval;
  1100.     }
  1101.     }
  1102.  
  1103.     *option_end = c;            /* put back for error messages */
  1104.     *arg = option_end;
  1105.  
  1106.     return ret;
  1107. }
  1108.  
  1109. /*
  1110.  * Allocate a variable for an string constant.
  1111.  * Return OK or FAIL.
  1112.  */
  1113.     static int
  1114. get_string_var(arg, retvar)
  1115.     char_u    **arg;
  1116.     VAR        retvar;
  1117. {
  1118.     char_u    *p;
  1119.     char_u    *name;
  1120.     int        i;
  1121.     int        mod;
  1122.  
  1123.     /*
  1124.      * Find the end of the string, skipping backslashed characters.
  1125.      */
  1126.     for (p = *arg + 1; *p && *p != '\"'; ++p)
  1127.     if (*p == '\\' && p[1] != NUL)
  1128.         ++p;
  1129.     if (*p != '\"')
  1130.     {
  1131.     EMSG2("Missing quote: %s", *arg);
  1132.     return FAIL;
  1133.     }
  1134.  
  1135.     /*
  1136.      * Copy the string into allocated memory, handling backslashed
  1137.      * characters.
  1138.      */
  1139.     name = alloc((unsigned)(p - *arg));
  1140.     if (name == NULL)
  1141.     return FAIL;
  1142.  
  1143.     i = 0;
  1144.     for (p = *arg + 1; *p && *p != '\"'; ++p)
  1145.     {
  1146.     if (*p == '\\')
  1147.     {
  1148.         switch (*++p)
  1149.         {
  1150.         case 'b': name[i++] = BS; break;
  1151.         case 'e': name[i++] = ESC; break;
  1152.         case 'f': name[i++] = FF; break;
  1153.         case 'n': name[i++] = NL; break;
  1154.         case 'r': name[i++] = CR; break;
  1155.         case 't': name[i++] = TAB; break;
  1156.  
  1157.               /* hex: "\x1", "\x12" */
  1158.         case 'X':
  1159.         case 'x': if (isxdigit(p[1]))
  1160.               {
  1161.                   ++p;
  1162.                   name[i] = hex2nr(*p);
  1163.                   if (isxdigit(p[1]))
  1164.                   {
  1165.                   ++p;
  1166.                   name[i] = (name[i] << 4) + hex2nr(*p);
  1167.                   }
  1168.                   ++i;
  1169.               }
  1170.               else
  1171.                   name[i++] = *p;
  1172.               break;
  1173.  
  1174.               /* octal: "\1", "\12", "\123" */
  1175.         case '0':
  1176.         case '1':
  1177.         case '2':
  1178.         case '3':
  1179.         case '4':
  1180.         case '5':
  1181.         case '6':
  1182.         case '7': name[i] = *p - '0';
  1183.               if (p[1] >= '0' && p[1] <= '7')
  1184.               {
  1185.                   ++p;
  1186.                   name[i] = (name[i] << 3) + *p - '0';
  1187.                   if (p[1] >= '0' && p[1] <= '7')
  1188.                   {
  1189.                   ++p;
  1190.                   name[i] = (name[i] << 3) + *p - '0';
  1191.                   }
  1192.               }
  1193.               ++i;
  1194.               break;
  1195.  
  1196.                 /* Special key, e.g.: <C-W> */
  1197.         case '<': name[i] = find_special_key(&p, &mod);
  1198.               if (name[i])
  1199.               {
  1200.                   ++i;
  1201.                   --p;
  1202.                   break;
  1203.               }
  1204.               /* FALLTHROUGH */
  1205.  
  1206.         default:  name[i++] = *p;
  1207.               break;
  1208.         }
  1209.     }
  1210.     else
  1211.         name[i++] = *p;
  1212.     }
  1213.     name[i] = NUL;
  1214.     *arg = p + 1;
  1215.  
  1216.     retvar->var_type = VAR_STRING;
  1217.     retvar->var_val.var_string = name;
  1218.  
  1219.     return OK;
  1220. }
  1221.  
  1222. /*
  1223.  * Allocate a variable for an backtick-string constant.
  1224.  * Return OK or FAIL.
  1225.  */
  1226.     static int
  1227. get_lit_string_var(arg, retvar)
  1228.     char_u    **arg;
  1229.     VAR        retvar;
  1230. {
  1231.     char_u    *p;
  1232.     char_u    *name;
  1233.  
  1234.     /*
  1235.      * Find the end of the string.
  1236.      */
  1237.     p = vim_strchr(*arg + 1, '\'');
  1238.     if (p == NULL)
  1239.     {
  1240.     EMSG2("Missing quote: %s", *arg);
  1241.     return FAIL;
  1242.     }
  1243.  
  1244.     /*
  1245.      * Copy the string into allocated memory.
  1246.      */
  1247.     name = vim_strnsave(*arg + 1, (int)(p - (*arg + 1)));
  1248.     if (name == NULL)
  1249.     return FAIL;
  1250.  
  1251.     *arg = p + 1;
  1252.  
  1253.     retvar->var_type = VAR_STRING;
  1254.     retvar->var_val.var_string = name;
  1255.  
  1256.     return OK;
  1257. }
  1258.  
  1259. /*
  1260.  * Get the value of an environment variable.
  1261.  * Return OK or FAIL.
  1262.  */
  1263.     static int
  1264. get_env_var(arg, retvar)
  1265.     char_u    **arg;
  1266.     VAR        retvar;
  1267. {
  1268.     char_u    *string;
  1269.  
  1270.     string = get_env_string(arg);
  1271.  
  1272.     /*
  1273.      * Allocate a variable.  If the environment variable was not set, silently
  1274.      * assume it is empty.
  1275.      */
  1276.     if (string != NULL)
  1277.     string = vim_strsave(string);
  1278.     retvar->var_type = VAR_STRING;
  1279.     retvar->var_val.var_string = string;
  1280.  
  1281.     return OK;
  1282. }
  1283.  
  1284. /*
  1285.  * Allocate a variable for the result of a function.
  1286.  * Return OK or FAIL.
  1287.  */
  1288.     static int
  1289. get_func_var(name, len, retvar, arg)
  1290.     char_u    *name;        /* name of the function */
  1291.     int        len;        /* length of "name" */
  1292.     VAR        retvar;
  1293.     char_u    **arg;        /* argument, pointing to the '(' */
  1294. {
  1295.     char_u    *argp;
  1296.     int        ret = FAIL;
  1297. #define MAX_FUNC_ARGS    4
  1298.     var        argvars[MAX_FUNC_ARGS];    /* vars for arguments */
  1299.     int        argcount = 0;        /* number of arguments found */
  1300. #define ERROR_NONE    0
  1301. #define ERROR_INVARG    1
  1302. #define ERROR_UNKOWN    2
  1303. #define ERROR_OTHER    3
  1304.     int        error = ERROR_NONE;
  1305.     int        i;
  1306.     int        cc;
  1307.     static struct fst
  1308.     {
  1309.     char    *f_name;    /* function name */
  1310.     char    f_argcount;    /* number of arguments */
  1311.     void    (*f_func) __ARGS((VAR args, VAR rvar));    /* impl. function */
  1312.     } functions[] =
  1313.     {{"buffer_exists",        1, f_buffer_exists},
  1314.      {"buffer_name",        1, f_buffer_name},
  1315.      {"buffer_number",        1, f_buffer_number},
  1316.      {"char2nr",        1, f_char2nr},
  1317.      {"col",            1, f_col},
  1318.      {"delete",            1, f_delete},
  1319.      {"exists",            1, f_exists},
  1320.      {"expand",            1, f_expand},
  1321.      {"file_readable",        1, f_file_readable},
  1322.      {"getcwd",            0, f_getcwd},
  1323.      {"getline",        1, f_getline},
  1324.      {"has",            1, f_has},
  1325.      {"highlight_exists",   1, f_highlight_exists},
  1326.      {"highlightID",        1, f_highlightID},
  1327.      {"hostname",        0, f_hostname},
  1328.      {"isdirectory",        1, f_isdirectory},
  1329.      {"last_buffer_nr",        0, f_last_buffer_nr},
  1330.      {"line",            1, f_line},
  1331.      {"match",            2, f_match},
  1332.      {"matchend",        2, f_matchend},
  1333.      {"nr2char",        1, f_nr2char},
  1334. #ifdef HAVE_STRFTIME
  1335.      {"strftime",        1, f_strftime},
  1336. #endif
  1337.      {"strlen",            1, f_strlen},
  1338.      {"strpart",        3, f_strpart},
  1339.      {"synID",            3, f_synID},
  1340.      {"synIDattr",        2, f_synIDattr},
  1341.      {"synIDtrans",        1, f_synIDtrans},
  1342.      {"substitute",        4, f_substitute},
  1343.      {"tempname",        0, f_tempname},
  1344.      {"virtcol",        1, f_virtcol},
  1345.      {"winheight",        1, f_winheight},
  1346.     };
  1347.  
  1348.     cc = name[len];
  1349.     name[len] = NUL;
  1350.  
  1351.     /*
  1352.      * Get the arguments.
  1353.      */
  1354.     argp = *arg;
  1355.     while (argcount < MAX_FUNC_ARGS)
  1356.     {
  1357.     argp = skipwhite(argp + 1);        /* skip the '(' or ',' */
  1358.     if (*argp == ')')
  1359.         break;
  1360.     if (eval1(&argp, &argvars[argcount]) == FAIL)
  1361.     {
  1362.         error = ERROR_OTHER;
  1363.         break;
  1364.     }
  1365.     ++argcount;
  1366.     if (*argp != ',')
  1367.         break;
  1368.     }
  1369.     if (*argp != ')' && error == ERROR_NONE)
  1370.     error = ERROR_INVARG;
  1371.  
  1372.     if (error == ERROR_NONE)
  1373.     {
  1374.     retvar->var_type = VAR_NUMBER;    /* default is number retvar */
  1375.  
  1376.     /*
  1377.      * Find the function name in the table, call its implementation.
  1378.      */
  1379.     error = ERROR_UNKOWN;
  1380.     for (i = 0; i < (int)(sizeof(functions) / sizeof(struct fst)); ++i)
  1381.         if (STRCMP(name, functions[i].f_name) == 0)
  1382.         {
  1383.         if (argcount != functions[i].f_argcount)
  1384.             error = ERROR_INVARG;
  1385.         else
  1386.         {
  1387.             functions[i].f_func(argvars, retvar);
  1388.             error = ERROR_NONE;
  1389.         }
  1390.         break;
  1391.         }
  1392.  
  1393.     if (error == ERROR_UNKOWN)
  1394.         EMSG2("Unknown function: %s", name);
  1395.  
  1396.     *arg = skipwhite(argp + 1);
  1397.     if (error == ERROR_NONE)
  1398.         ret = OK;
  1399.     }
  1400.  
  1401.     while (--argcount >= 0)
  1402.     clear_var(&argvars[argcount]);
  1403.  
  1404.     if (error == ERROR_INVARG)
  1405.     EMSG2("Invalid arguments for function %s", name);
  1406.  
  1407.     name[len] = cc;
  1408.  
  1409.     return ret;
  1410. }
  1411.  
  1412.     static BUF *
  1413. get_buf_var(avar)
  1414.     VAR        avar;
  1415. {
  1416.     char_u    *name = avar->var_val.var_string;
  1417.  
  1418.     if (avar->var_type == VAR_NUMBER)
  1419.     return buflist_findnr((int)avar->var_val.var_number);
  1420.     else if (name == NULL || *name == NUL)
  1421.     return curbuf;
  1422.     else
  1423.     return buflist_findnr(buflist_findpat(name, name + STRLEN(name)));
  1424. }
  1425.  
  1426. /*
  1427.  * "buffer_name()" function.
  1428.  */
  1429.     static void
  1430. f_buffer_name(argvars, retvar)
  1431.     VAR        argvars;
  1432.     VAR        retvar;
  1433. {
  1434.     BUF        *buf;
  1435.  
  1436.     ++emsg_off;
  1437.     buf = get_buf_var(&argvars[0]);
  1438.     retvar->var_type = VAR_STRING;
  1439.     if (buf != NULL && buf->b_fname != NULL)
  1440.     retvar->var_val.var_string = vim_strsave(buf->b_fname);
  1441.     else
  1442.     retvar->var_val.var_string = NULL;
  1443.     --emsg_off;
  1444. }
  1445.  
  1446. /*
  1447.  * "buffer_number()" function.
  1448.  */
  1449.     static void
  1450. f_buffer_number(argvars, retvar)
  1451.     VAR        argvars;
  1452.     VAR        retvar;
  1453. {
  1454.     BUF        *buf;
  1455.  
  1456.     ++emsg_off;
  1457.     buf = get_buf_var(&argvars[0]);
  1458.     if (buf != NULL)
  1459.     retvar->var_val.var_number = buf->b_fnum; 
  1460.     else
  1461.     retvar->var_val.var_number = -1;
  1462.     --emsg_off;
  1463. }
  1464.  
  1465. /*
  1466.  * "buffer_exists()" function.
  1467.  */
  1468.     static void
  1469. f_buffer_exists(argvars, retvar)
  1470.     VAR        argvars;
  1471.     VAR        retvar;
  1472. {
  1473.     int        n = FALSE;
  1474.     char_u    *name;
  1475.  
  1476.     if (argvars[0].var_type == VAR_NUMBER)
  1477.     n = (buflist_findnr((int)argvars[0].var_val.var_number) != NULL);
  1478.     else if (argvars[0].var_val.var_string != NULL)
  1479.     {
  1480.     /* First make the name into a full path name */
  1481.     name = FullName_save(argvars[0].var_val.var_string,
  1482. #ifdef UNIX
  1483.         TRUE        /* force expansion, get rid of symbolic links */
  1484. #else
  1485.         FALSE
  1486. #endif
  1487.         );
  1488.     if (name != NULL)
  1489.     {
  1490.         n = (buflist_findname(name) != NULL);
  1491.         vim_free(name);
  1492.     }
  1493.     }
  1494.  
  1495.     retvar->var_val.var_number = n;
  1496. }
  1497.  
  1498. /*
  1499.  * "char2nr()" function
  1500.  */
  1501.     static void
  1502. f_char2nr(argvars, retvar)
  1503.     VAR        argvars;
  1504.     VAR        retvar;
  1505. {
  1506.     retvar->var_val.var_number = get_var_string(&argvars[0])[0];
  1507. }
  1508.  
  1509. /*
  1510.  * "col(string)" function
  1511.  */
  1512.     static void
  1513. f_col(argvars, retvar)
  1514.     VAR        argvars;
  1515.     VAR        retvar;
  1516. {
  1517.     colnr_t    col = 0;
  1518.     FPOS    *fp;
  1519.  
  1520.     fp = var2fpos(&argvars[0]);
  1521.     if (fp != NULL && fp->lnum > 0)
  1522.     col = fp->col + 1;
  1523.  
  1524.     retvar->var_val.var_number = col;
  1525. }
  1526.  
  1527. /*
  1528.  * "delete()" function
  1529.  */
  1530.     static void
  1531. f_delete(argvars, retvar)
  1532.     VAR        argvars;
  1533.     VAR        retvar;
  1534. {
  1535.     retvar->var_val.var_number = vim_remove(get_var_string(&argvars[0]));
  1536. }
  1537.  
  1538. /*
  1539.  * "exists()" function
  1540.  */
  1541.     static void
  1542. f_exists(argvars, retvar)
  1543.     VAR        argvars;
  1544.     VAR        retvar;
  1545. {
  1546.     char_u    *p;
  1547.     char_u    *name;
  1548.     int        n = FALSE;
  1549.     int        len;
  1550.  
  1551.     p = get_var_string(&argvars[0]);
  1552.     if (*p == '$')            /* environment variable */
  1553.     n = (get_env_string(&p) != NULL);
  1554.     else if (*p == '&')            /* option */
  1555.     n = (get_option_var(&p, NULL) == OK);
  1556.     else                /* internal variable */
  1557.     {
  1558.     name = p;
  1559.     len = get_id_len(&p);
  1560.     if (len != 0)
  1561.         n = (get_var_var(name, len, NULL) == OK);
  1562.     }
  1563.  
  1564.     retvar->var_val.var_number = n;
  1565. }
  1566.  
  1567. /*
  1568.  * "expand()" function
  1569.  */
  1570.     static void
  1571. f_expand(argvars, retvar)
  1572.     VAR        argvars;
  1573.     VAR        retvar;
  1574. {
  1575.     char_u    *s;
  1576.     int        len;
  1577.     char_u    *errormsg;
  1578.  
  1579.     retvar->var_type = VAR_STRING;
  1580.     s = get_var_string(&argvars[0]);
  1581.     if (*s == '%' || *s == '#' || *s == '<')
  1582.     retvar->var_val.var_string = eval_vars(s, &len, NULL, &errormsg);
  1583.     else
  1584.     retvar->var_val.var_string = ExpandOne(s, NULL, WILD_USE_NL, WILD_ALL);
  1585. }
  1586.  
  1587. /*
  1588.  * "file_readable()" function
  1589.  */
  1590.     static void
  1591. f_file_readable(argvars, retvar)
  1592.     VAR        argvars;
  1593.     VAR        retvar;
  1594. {
  1595.     FILE    *fd;
  1596.     char_u    *p;
  1597.     int        n;
  1598.  
  1599.     p = get_var_string(&argvars[0]);
  1600.     if (!mch_isdir(p) && (fd = fopen((char *)p, "r")) != NULL)
  1601.     {
  1602.     n = TRUE;
  1603.     fclose(fd);
  1604.     }
  1605.     else
  1606.     n = FALSE;
  1607.  
  1608.     retvar->var_val.var_number = n;
  1609. }
  1610.  
  1611. /*
  1612.  * "getcwd()" function
  1613.  */
  1614. /*ARGSUSED*/
  1615.     static void
  1616. f_getcwd(argvars, retvar)
  1617.     VAR        argvars;
  1618.     VAR        retvar;
  1619. {
  1620.     char_u    cwd[MAXPATHL];
  1621.  
  1622.     retvar->var_type = VAR_STRING;
  1623.     if (mch_dirname(cwd, MAXPATHL) == FAIL)
  1624.     retvar->var_val.var_string = NULL;
  1625.     else
  1626.     retvar->var_val.var_string = vim_strsave(cwd);
  1627. }
  1628.  
  1629. /*
  1630.  * "getline(lnum)" function
  1631.  */
  1632.     static void
  1633. f_getline(argvars, retvar)
  1634.     VAR        argvars;
  1635.     VAR        retvar;
  1636. {
  1637.     linenr_t    lnum;
  1638.     char_u    *p;
  1639.  
  1640.     lnum = get_var_number(&argvars[0]);
  1641.     if (lnum == 0)  /* no valid number, try using line() */
  1642.     {
  1643.     f_line(argvars, retvar);
  1644.     lnum = retvar->var_val.var_number;
  1645.     clear_var(retvar);
  1646.     }
  1647.  
  1648.     if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count)
  1649.     p = ml_get(lnum);
  1650.     else
  1651.     p = (char_u *)"";
  1652.  
  1653.     retvar->var_type = VAR_STRING;
  1654.     retvar->var_val.var_string = vim_strsave(p);
  1655. }
  1656.  
  1657. /*
  1658.  * "has()" function
  1659.  */
  1660.     static void
  1661. f_has(argvars, retvar)
  1662.     VAR        argvars;
  1663.     VAR        retvar;
  1664. {
  1665.     int        i;
  1666.     char_u    *name;
  1667.     int        n = FALSE;
  1668.     static char    *(has_list[]) =
  1669.     {
  1670. #ifdef MSDOS
  1671. # ifdef DJGPP
  1672.     "dos32",
  1673. # else
  1674.     "dos16",
  1675. # endif
  1676. #endif
  1677. #ifdef WIN32
  1678.     "win32",
  1679. #endif
  1680. #ifdef AMIGA
  1681.     "amiga",
  1682. # ifndef NO_ARP
  1683.     "arp",
  1684. # endif
  1685. #endif
  1686. #ifdef __BEOS__
  1687.     "beos",
  1688. #endif
  1689. #ifdef macintosh
  1690.     "mac",
  1691. #endif
  1692. #ifdef UNIX
  1693.     "unix",
  1694. #endif
  1695. #ifndef CASE_INSENSITIVE_FILENAME
  1696.     "fname_case",
  1697. #endif
  1698. #ifdef AUTOCMD
  1699.     "autocmd",
  1700. #endif
  1701. #if defined(SOME_BUILTIN_TCAPS) || defined(ALL_BUILTIN_TCAPS)
  1702.     "builtin_terms",
  1703. # ifdef ALL_BUILTIN_TCAPS
  1704.     "all_builtin_terms",
  1705. # endif
  1706. #endif
  1707. #ifdef CINDENT
  1708.     "cindent",
  1709. #endif
  1710. #ifdef DEBUG
  1711.     "debug",
  1712. #endif
  1713. #ifdef DIGRAPHS
  1714.     "digraphs",
  1715. #endif
  1716. #ifdef EMACS_TAGS
  1717.     "emacs_tags",
  1718. #endif
  1719.     "eval",        /* always present, of course! */
  1720. #ifdef EX_EXTRA
  1721.     "ex_extra",
  1722. #endif
  1723. #ifdef EXTRA_SEARCH
  1724.     "extra_search",
  1725. #endif
  1726. #ifdef FKMAP
  1727.     "farsi",
  1728. #endif
  1729. #ifdef FILE_IN_PATH
  1730.     "file_in_path",
  1731. #endif
  1732. #ifdef FIND_IN_PATH
  1733.     "find_in_path",
  1734. #endif
  1735. #if !defined(USE_SYSTEM) && defined(UNIX)
  1736.     "fork",
  1737. #endif
  1738. #ifdef USE_GUI
  1739.     "gui",
  1740. #endif
  1741. #ifdef USE_GUI_ATHENA
  1742.     "gui_athena",
  1743. #endif
  1744. #ifdef USE_GUI_BEOS
  1745.     "gui_beos",
  1746. #endif
  1747. #ifdef USE_GUI_MAC
  1748.     "gui_mac",
  1749. #endif
  1750. #ifdef USE_GUI_MOTIF
  1751.     "gui_motif",
  1752. #endif
  1753. #ifdef USE_GUI_WIN32
  1754.     "gui_win32",
  1755. #endif
  1756. #ifdef INSERT_EXPAND
  1757.     "insert_expand",
  1758. #endif
  1759. #ifdef HAVE_LANGMAP
  1760.     "langmap",
  1761. #endif
  1762. #ifdef LISPINDENT
  1763.     "lispindent",
  1764. #endif
  1765. #ifdef USE_MOUSE
  1766.     "mouse",
  1767. #endif
  1768. #ifdef UNIX
  1769. # ifdef DEC_MOUSE
  1770.     "mouse_dec",
  1771. # endif
  1772. # ifdef NETTERM_MOUSE
  1773.     "mouse_netterm",
  1774. # endif
  1775. # ifdef XTERM_MOUSE
  1776.     "mouse_xterm",
  1777. # endif
  1778. #endif
  1779. #ifdef HAVE_OLE
  1780.     "ole",
  1781. #endif
  1782. #ifdef HAVE_PERL_INTERP
  1783.     "perl",
  1784. #endif
  1785. #ifdef HAVE_PYTHON
  1786.     "python",
  1787. #endif
  1788. #ifdef QUICKFIX
  1789.     "quickfix",
  1790. #endif
  1791. #ifdef RIGHTLEFT
  1792.     "rightleft",
  1793. #endif
  1794. #ifdef SHOWCMD
  1795.     "showcmd",
  1796. #endif
  1797. #ifdef SMARTINDENT
  1798.     "smartindent",
  1799. #endif
  1800. #ifdef SYNTAX_HL
  1801.     "syntax",
  1802. #endif
  1803. #if defined(USE_SYSTEM) || !defined(UNIX)
  1804.     "system",
  1805. #endif
  1806. #ifdef BINARY_TAGS
  1807.     "tag_binary",
  1808. #endif
  1809. #ifdef OLD_STATIC_TAGS
  1810.     "tag_old_static",
  1811. #endif
  1812. #ifdef TAG_ANY_WHITE
  1813.     "tag_any_white",
  1814. #endif
  1815. #ifdef TERMINFO
  1816.     "terminfo",
  1817. #endif
  1818. #ifdef TEXT_OBJECTS
  1819.     "textobjects",
  1820. #endif
  1821. #ifdef HAVE_TGETENT
  1822.     "tgetent",
  1823. #endif
  1824. #ifdef VIMINFO
  1825.     "viminfo",
  1826. #endif
  1827. #ifdef WRITEBACKUP
  1828.     "writebackup",
  1829. #endif
  1830. #ifdef SAVE_XTERM_SCREEN
  1831.     "xterm_save",
  1832. #endif
  1833. #if defined(UNIX) && defined(WANT_X11) && defined(HAVE_X11)
  1834.     "X11",
  1835. #endif
  1836.     NULL
  1837.     };
  1838.  
  1839.     name = get_var_string(&argvars[0]);
  1840.     for (i = 0; has_list[i] != NULL; ++i)
  1841.     if (STRICMP(name, has_list[i]) == 0)
  1842.     {
  1843.         n = TRUE;
  1844.         break;
  1845.     }
  1846.  
  1847.     if (n == FALSE)
  1848.     {
  1849. #ifdef USE_GUI
  1850.     if (STRICMP(name, "gui_running") == 0)
  1851.     {
  1852.         n = (gui.in_use || gui.starting);
  1853.     }
  1854. # ifdef USE_GUI_WIN32
  1855.     else if (STRICMP(name, "gui_win32s") == 0)
  1856.     {
  1857.         n = gui_is_win32s();
  1858.     }
  1859. # endif
  1860. #endif
  1861. #ifdef SYNTAX_HL
  1862. # ifdef USE_GUI
  1863.     else
  1864. # endif
  1865.         if (STRICMP(name, "syntax_items") == 0)
  1866.     {
  1867.         n = syntax_present(curbuf);
  1868.     }
  1869. #endif
  1870.     }
  1871.  
  1872.     retvar->var_val.var_number = n;
  1873. }
  1874.  
  1875. /*
  1876.  * "highlight_exists()" function
  1877.  */
  1878.     static void
  1879. f_highlight_exists(argvars, retvar)
  1880.     VAR        argvars;
  1881.     VAR        retvar;
  1882. {
  1883.     retvar->var_val.var_number = highlight_exists(get_var_string(&argvars[0]));
  1884. }
  1885.  
  1886. /*
  1887.  * "highlightID(name)" function
  1888.  */
  1889.     static void
  1890. f_highlightID(argvars, retvar)
  1891.     VAR        argvars;
  1892.     VAR        retvar;
  1893. {
  1894.     retvar->var_val.var_number = syn_name2id(get_var_string(&argvars[0]));
  1895. }
  1896.  
  1897. /*
  1898.  * "hostname()" function
  1899.  */
  1900. /*ARGSUSED*/
  1901.     static void
  1902. f_hostname(argvars, retvar)
  1903.     VAR        argvars;
  1904.     VAR        retvar;
  1905. {
  1906.     char_u hostname[256];
  1907.  
  1908.     mch_get_host_name(hostname, 256);
  1909.     retvar->var_type = VAR_STRING;
  1910.     retvar->var_val.var_string = vim_strsave(hostname);
  1911. }
  1912.  
  1913. /*
  1914.  * "isdirectory()" function
  1915.  */
  1916.     static void
  1917. f_isdirectory(argvars, retvar)
  1918.     VAR        argvars;
  1919.     VAR        retvar;
  1920. {
  1921.     retvar->var_val.var_number = mch_isdir(get_var_string(&argvars[0]));
  1922. }
  1923.  
  1924. /*
  1925.  * "last_buffer_nr()" function.
  1926.  */
  1927. /*ARGSUSED*/
  1928.     static void
  1929. f_last_buffer_nr(argvars, retvar)
  1930.     VAR        argvars;
  1931.     VAR        retvar;
  1932. {
  1933.     int        n = 0;
  1934.     BUF        *buf;
  1935.  
  1936.     for (buf = firstbuf; buf != NULL; buf = buf->b_next)
  1937.     if (n < buf->b_fnum)
  1938.         n = buf->b_fnum;
  1939.  
  1940.     retvar->var_val.var_number = n;
  1941. }
  1942.  
  1943. /*
  1944.  * "line(string)" function
  1945.  */
  1946.     static void
  1947. f_line(argvars, retvar)
  1948.     VAR        argvars;
  1949.     VAR        retvar;
  1950. {
  1951.     linenr_t    lnum = 0;
  1952.     FPOS    *fp;
  1953.  
  1954.     fp = var2fpos(&argvars[0]);
  1955.     if (fp != NULL)
  1956.     lnum = fp->lnum;
  1957.     else if (get_var_string(&argvars[0])[0] == '$')   /* last line in buffer */
  1958.     lnum = curbuf->b_ml.ml_line_count;
  1959.  
  1960.     retvar->var_val.var_number = lnum;
  1961. }
  1962.  
  1963. /*
  1964.  * "match()" function
  1965.  */
  1966.     static void
  1967. f_match(argvars, retvar)
  1968.     VAR        argvars;
  1969.     VAR        retvar;
  1970. {
  1971.     f_some_match(argvars, retvar, TRUE);
  1972. }
  1973.  
  1974. /*
  1975.  * "matchend()" function
  1976.  */
  1977.     static void
  1978. f_matchend(argvars, retvar)
  1979.     VAR        argvars;
  1980.     VAR        retvar;
  1981. {
  1982.     f_some_match(argvars, retvar, FALSE);
  1983. }
  1984.  
  1985.     static void
  1986. f_some_match(argvars, retvar, start)
  1987.     VAR        argvars;
  1988.     VAR        retvar;
  1989.     int        start;
  1990. {
  1991.     char_u        *str;
  1992.     char_u        *pat;
  1993.     int            n = -1;
  1994.     vim_regexp        *prog;
  1995.     char_u        patbuf[NUMBUFLEN];
  1996.  
  1997.     str = get_var_string(&argvars[0]);
  1998.     pat = get_var_string_buf(&argvars[1], patbuf);
  1999.  
  2000.     reg_ic = p_ic;
  2001.     prog = vim_regcomp(pat, TRUE);
  2002.     if (prog != NULL)
  2003.     {
  2004.     if (vim_regexec(prog, str, TRUE))
  2005.     {
  2006.         if (start)
  2007.         n = prog->startp[0] - str;
  2008.         else
  2009.         n = prog->endp[0] - str;
  2010.     }
  2011.     vim_free(prog);
  2012.     }
  2013.     retvar->var_val.var_number = n;
  2014. }
  2015.  
  2016. /*
  2017.  * "nr2char()" function
  2018.  */
  2019.     static void
  2020. f_nr2char(argvars, retvar)
  2021.     VAR        argvars;
  2022.     VAR        retvar;
  2023. {
  2024.     char_u    buf[2];
  2025.  
  2026.     buf[0] = (char_u)get_var_number(&argvars[0]);
  2027.     retvar->var_type = VAR_STRING;
  2028.     retvar->var_val.var_string = vim_strnsave(buf, 1);
  2029. }
  2030.  
  2031. #ifdef HAVE_STRFTIME
  2032. /*
  2033.  * "strftime()" function
  2034.  */
  2035.     static void
  2036. f_strftime(argvars, retvar)
  2037.     VAR        argvars;
  2038.     VAR        retvar;
  2039. {
  2040.     char_u    result_buf[80];
  2041.     struct tm    *curtime;
  2042.     time_t    seconds;
  2043.     char_u    *p;
  2044.  
  2045.     p = get_var_string(&argvars[0]);
  2046.     seconds = time(NULL);
  2047.     curtime = localtime(&seconds);
  2048.     (void)strftime((char *)result_buf, (size_t)80, (char *)p, curtime);
  2049.  
  2050.     retvar->var_type = VAR_STRING;
  2051.     retvar->var_val.var_string = vim_strsave(result_buf);
  2052. }
  2053. #endif
  2054.  
  2055. /*
  2056.  * "strlen()" function
  2057.  */
  2058.     static void
  2059. f_strlen(argvars, retvar)
  2060.     VAR        argvars;
  2061.     VAR        retvar;
  2062. {
  2063.     retvar->var_val.var_number = STRLEN(get_var_string(&argvars[0]));
  2064. }
  2065.  
  2066. /*
  2067.  * "strpart()" function
  2068.  */
  2069.     static void
  2070. f_strpart(argvars, retvar)
  2071.     VAR        argvars;
  2072.     VAR        retvar;
  2073. {
  2074.     char_u    *p;
  2075.     int        n;
  2076.     int        len;
  2077.     int        slen;
  2078.  
  2079.     p = get_var_string(&argvars[0]);
  2080.     n = get_var_number(&argvars[1]);
  2081.     len = get_var_number(&argvars[2]);
  2082.     slen = STRLEN(p);
  2083.     /*
  2084.      * Only return the overlap between the specified part and the actual
  2085.      * string.
  2086.      */
  2087.     if (n < 0)
  2088.     {
  2089.     len += n;
  2090.     n = 0;
  2091.     }
  2092.     else if (n > slen)
  2093.     n = slen;
  2094.     if (len < 0)
  2095.     len = 0;
  2096.     else if (n + len > slen)
  2097.     len = slen - n;
  2098.  
  2099.     retvar->var_type = VAR_STRING;
  2100.     retvar->var_val.var_string = vim_strnsave(p + n, len);
  2101. }
  2102.  
  2103. /*
  2104.  * "synID(line, col, trans)" function
  2105.  */
  2106.     static void
  2107. f_synID(argvars, retvar)
  2108.     VAR        argvars;
  2109.     VAR        retvar;
  2110. {
  2111.     int        id = 0;
  2112. #ifdef SYNTAX_HL
  2113.     long    line;
  2114.     long    col;
  2115.     int        trans;
  2116.  
  2117.     line = get_var_number(&argvars[0]);
  2118.     col = get_var_number(&argvars[1]) - 1;
  2119.     trans = get_var_number(&argvars[2]);
  2120.  
  2121.     if (line >= 1 && line <= curbuf->b_ml.ml_line_count
  2122.         && col >= 0 && col < (long)STRLEN(ml_get(line)))
  2123.     id = syn_get_id(line, col, trans);
  2124. #endif
  2125.  
  2126.     retvar->var_val.var_number = id;
  2127. }
  2128.  
  2129. /*
  2130.  * "synIDattr(id, what)" function
  2131.  */
  2132.     static void
  2133. f_synIDattr(argvars, retvar)
  2134.     VAR        argvars;
  2135.     VAR        retvar;
  2136. {
  2137.     char_u    *p = NULL;
  2138. #ifdef SYNTAX_HL
  2139.     int        id;
  2140.     char_u    *what;
  2141.  
  2142.     id = get_var_number(&argvars[0]);
  2143.     what = get_var_string(&argvars[1]);
  2144.  
  2145.     switch (TO_LOWER(what[0]))
  2146.     {
  2147.     case 'b':
  2148.         if (TO_LOWER(what[1]) == 'g')        /* bg[#] */
  2149.             p = highlight_color(id, what);
  2150.         else                    /* bold */
  2151.             p = highlight_has_attr(id, HL_BOLD);
  2152.         break;
  2153.  
  2154.     case 'f':                    /* fg[#] */
  2155.         p = highlight_color(id, what);
  2156.         break;
  2157.  
  2158.     case 'i':
  2159.         if (TO_LOWER(what[1]) == 'n')        /* inverse */
  2160.             p = highlight_has_attr(id, HL_INVERSE);
  2161.         else                    /* italic */
  2162.             p = highlight_has_attr(id, HL_ITALIC);
  2163.         break;
  2164.  
  2165.     case 'n':                    /* name */
  2166.         p = get_highlight_name(id - 1);
  2167.         break;
  2168.  
  2169.     case 'r':                    /* reverse */
  2170.         p = highlight_has_attr(id, HL_INVERSE);
  2171.         break;
  2172.  
  2173.     case 's':                    /* standout */
  2174.         p = highlight_has_attr(id, HL_STANDOUT);
  2175.         break;
  2176.  
  2177.     case 'u':                    /* underline */
  2178.         p = highlight_has_attr(id, HL_UNDERLINE);
  2179.         break;
  2180.     }
  2181.  
  2182.     if (p != NULL)
  2183.     p = vim_strsave(p);
  2184. #endif
  2185.     retvar->var_type = VAR_STRING;
  2186.     retvar->var_val.var_string = p;
  2187. }
  2188.  
  2189. /*
  2190.  * "synIDtrans(id)" function
  2191.  */
  2192.     static void
  2193. f_synIDtrans(argvars, retvar)
  2194.     VAR        argvars;
  2195.     VAR        retvar;
  2196. {
  2197.     int        id;
  2198.  
  2199. #ifdef SYNTAX_HL
  2200.     id = get_var_number(&argvars[0]);
  2201.  
  2202.     if (id > 0)
  2203.     id = syn_get_final_id(id);
  2204.     else
  2205. #endif
  2206.     id = 0;
  2207.  
  2208.     retvar->var_val.var_number = id;
  2209. }
  2210.  
  2211. /*
  2212.  * "substitute()" function
  2213.  */
  2214.     static void
  2215. f_substitute(argvars, retvar)
  2216.     VAR        argvars;
  2217.     VAR        retvar;
  2218. {
  2219.     char_u        *str;
  2220.     char_u        *pat;
  2221.     char_u        *sub;
  2222.     int            sublen;
  2223.     vim_regexp        *prog;
  2224.     int            i;
  2225.     char_u        patbuf[NUMBUFLEN];
  2226.     char_u        subbuf[NUMBUFLEN];
  2227.     char_u        flagsbuf[NUMBUFLEN];
  2228.     char_u        *flags;
  2229.     int            do_all;
  2230.     char_u        *tail = NULL;
  2231.     struct growarray    ga;
  2232.  
  2233.     ga.ga_itemsize = 1;
  2234.     ga.ga_growsize = 200;
  2235.     ga_init(&ga);
  2236.  
  2237.     str = get_var_string(&argvars[0]);
  2238.     pat = get_var_string_buf(&argvars[1], patbuf);
  2239.     sub = get_var_string_buf(&argvars[2], subbuf);
  2240.     flags = get_var_string_buf(&argvars[3], flagsbuf);
  2241.     do_all = (flags[0] == 'g');
  2242.  
  2243.     reg_ic = p_ic;
  2244.     prog = vim_regcomp(pat, TRUE);
  2245.     if (prog != NULL)
  2246.     {
  2247.     tail = str;
  2248.     while (vim_regexec(prog, tail, tail == str))
  2249.     {
  2250.         /*
  2251.          * Get some space for a temporary buffer to do the substitution
  2252.          * into.  It will contain:
  2253.          * - The text up to where the match is.
  2254.          * - The substituted text.
  2255.          * - The text after the match.
  2256.          */
  2257.         sublen = vim_regsub(prog, sub, tail, FALSE, TRUE);
  2258.         if (ga_grow(&ga, (int)(STRLEN(tail) + sublen -
  2259.                   (prog->endp[0] - prog->startp[0]))) == FAIL)
  2260.         {
  2261.         ga_clear(&ga);
  2262.         break;
  2263.         }
  2264.  
  2265.         /* copy the text up to where the match is */
  2266.         i = prog->startp[0] - tail;
  2267.         vim_memmove((char_u *)ga.ga_data + ga.ga_len, tail, (size_t)i);
  2268.         /* add the substituted text */
  2269.         (void)vim_regsub(prog, sub, (char_u *)ga.ga_data + ga.ga_len + i,
  2270.                                   TRUE, TRUE);
  2271.         ga.ga_len += i + sublen - 1;
  2272.         ga.ga_room -= i + sublen - 1;
  2273.         /* avoid getting stuck on a match with an empty string */
  2274.         if (tail == prog->endp[0])
  2275.         {
  2276.         *((char_u *)ga.ga_data + ga.ga_len) = *tail++;
  2277.         ++ga.ga_len;
  2278.         --ga.ga_room;
  2279.         }
  2280.         else
  2281.         {
  2282.         tail = prog->endp[0];
  2283.         if (*tail == NUL)
  2284.             break;
  2285.         }
  2286.         if (!do_all)
  2287.         break;
  2288.     }
  2289.  
  2290.     if (ga.ga_data != NULL)
  2291.         STRCPY((char *)ga.ga_data + ga.ga_len, tail);
  2292.  
  2293.     vim_free(prog);
  2294.     }
  2295.  
  2296.     retvar->var_type = VAR_STRING;
  2297.     retvar->var_val.var_string = vim_strsave(ga.ga_data == NULL
  2298.                         ? str : (char_u *)ga.ga_data);
  2299.     ga_clear(&ga);
  2300. }
  2301.  
  2302. /*
  2303.  * "tempname()" function
  2304.  */
  2305. /*ARGSUSED*/
  2306.     static void
  2307. f_tempname(argvars, retvar)
  2308.     VAR        argvars;
  2309.     VAR        retvar;
  2310. {
  2311.     static int    x = 'A';
  2312.  
  2313.     retvar->var_type = VAR_STRING;
  2314.     retvar->var_val.var_string = vim_tempname(x);
  2315.     /* advance 'x', so that there are at least 26 different names */
  2316.     if (x == 'Z')
  2317.     x = 'A';
  2318.     else
  2319.     ++x;
  2320. }
  2321.  
  2322. /*
  2323.  * "virtcol(string)" function
  2324.  */
  2325.     static void
  2326. f_virtcol(argvars, retvar)
  2327.     VAR        argvars;
  2328.     VAR        retvar;
  2329. {
  2330.     colnr_t    vcol = 0;
  2331.     FPOS    *fp;
  2332.  
  2333.     fp = var2fpos(&argvars[0]);
  2334.     if (fp != NULL)
  2335.     {
  2336.     getvcol(curwin, fp, NULL, NULL, &vcol);
  2337.     ++vcol;
  2338.     }
  2339.  
  2340.     retvar->var_val.var_number = vcol;
  2341. }
  2342.  
  2343. /*
  2344.  * "winheight(nr)" function
  2345.  */
  2346.     static void
  2347. f_winheight(argvars, retvar)
  2348.     VAR        argvars;
  2349.     VAR        retvar;
  2350. {
  2351.     int        nr;
  2352.     WIN        *wp;
  2353.  
  2354.     nr = get_var_number(&argvars[0]);
  2355.  
  2356.     if (nr == 0)
  2357.     retvar->var_val.var_number = curwin->w_height;
  2358.     else
  2359.     {
  2360.     retvar->var_val.var_number = 0;
  2361.     for (wp = firstwin; wp != NULL; wp = wp->w_next)
  2362.     {
  2363.         if (--nr <= 0)
  2364.         {
  2365.         retvar->var_val.var_number = wp->w_height;
  2366.         break;
  2367.         }
  2368.     }
  2369.     }
  2370. }
  2371.  
  2372. /*
  2373.  * Translate a String variable into a position (for col() and virtcol()).
  2374.  */
  2375.     static FPOS *
  2376. var2fpos(varp)
  2377.     VAR        varp;
  2378. {
  2379.     char_u    *name;
  2380.  
  2381.     name = get_var_string(varp);
  2382.     if (name[0] == '.')        /* cursor */
  2383.     return &curwin->w_cursor;
  2384.     if (name[0] == '\'')    /* mark */
  2385.     return getmark(name[1], FALSE);
  2386.     return NULL;
  2387. }
  2388.  
  2389. /*
  2390.  * Get the lenght of an environment variable name.
  2391.  * Advance "arg" to the first character after the name.
  2392.  * Return 0 for error.
  2393.  */
  2394.     static int
  2395. get_env_len(arg)
  2396.     char_u    **arg;
  2397. {
  2398.     char_u    *p;
  2399.     int        len;
  2400.  
  2401.     for (p = *arg; vim_isIDc(*p); ++p)
  2402.     ;
  2403.     if (p == *arg)        /* no name found */
  2404.     return 0;
  2405.  
  2406.     len = p - *arg;
  2407.     *arg = p;
  2408.     return len;
  2409. }
  2410.  
  2411. /*
  2412.  * Get the value of an environment variable.
  2413.  * "arg" points to the '$' before the env var name.
  2414.  * "arg" is advanced to the first character after the name.
  2415.  * Return NULL for failure.
  2416.  */
  2417.     char_u *
  2418. get_env_string(arg)
  2419.     char_u    **arg;
  2420. {
  2421.     int        len;
  2422.     int        cc;
  2423.     char_u  *name;
  2424.     char_u  *s;
  2425.  
  2426.     ++*arg;
  2427.     name = *arg;
  2428.     len = get_env_len(arg);
  2429.     if (len == 0)
  2430.     return NULL;
  2431.     cc = name[len];
  2432.     name[len] = NUL;
  2433.     s = vim_getenv(name);
  2434.     name[len] = cc;
  2435.  
  2436.     return s;
  2437. }
  2438.  
  2439. /*
  2440.  * Get the length of the name of a function or internal variable.
  2441.  * "arg" is advanced to the first non-white character after the name.
  2442.  * Return 0 if something is wrong.
  2443.  */
  2444.     static int
  2445. get_id_len(arg)
  2446.     char_u    **arg;
  2447. {
  2448.     char_u    *p;
  2449.     int        len;
  2450.  
  2451.     /* Find the end of the name. */
  2452.     for (p = *arg; eval_isnamec(*p); ++p)
  2453.     ;
  2454.     if (p == *arg)        /* no name found */
  2455.     return 0;
  2456.  
  2457.     len = p - *arg;
  2458.     *arg = skipwhite(p);
  2459.  
  2460.     return len;
  2461. }
  2462.  
  2463.     static int
  2464. eval_isnamec(c)
  2465.     int        c;
  2466. {
  2467.     return (isalpha(c) || isdigit(c) || c == '_' || c == ':');
  2468. }
  2469.  
  2470. /*
  2471.  * Get the value of internal variable "name".
  2472.  * Return OK or FAIL.
  2473.  */
  2474.     static int
  2475. get_var_var(name, len, retvar)
  2476.     char_u    *name;
  2477.     int        len;        /* length of "name" */
  2478.     VAR        retvar;        /* NULL when only checking existence */
  2479. {
  2480.     int        ret = OK;
  2481.     int        type = VAR_UNKNOWN;
  2482.     long    number = 1;
  2483.     char_u    *string = NULL;
  2484.     VAR        v;
  2485.     int        cc;
  2486.  
  2487.     cc = name[len];
  2488.     name[len] = NUL;
  2489.  
  2490.     /*
  2491.      * Check for built-in variables.
  2492.      */
  2493.     if (len == 7 && STRCMP(name, "version") == 0)
  2494.     {
  2495.     type = VAR_NUMBER;
  2496.     number = get_version();
  2497.     }
  2498.     else if (len == 5 && STRCMP(name, "count") == 0)
  2499.     {
  2500.     type = VAR_NUMBER;
  2501.     number = global_opnum;
  2502.     }
  2503.     else if (len == 11 && STRCMP(name, "shell_error") == 0)
  2504.     {
  2505.     type = VAR_NUMBER;
  2506.     number = (call_shell_retval == FAIL);
  2507.     }
  2508.  
  2509.     /*
  2510.      * Check for user-defined variables.
  2511.      */
  2512.     else
  2513.     {
  2514.     v = find_var(name);
  2515.     if (v != NULL)
  2516.     {
  2517.         type = v->var_type;
  2518.         number = v->var_val.var_number;
  2519.         string = v->var_val.var_string;
  2520.     }
  2521.     }
  2522.  
  2523.     if (type == VAR_UNKNOWN)
  2524.     {
  2525.     if (retvar != NULL)
  2526.         EMSG2("Undefined variable: %s", name);
  2527.     ret = FAIL;
  2528.     }
  2529.     else if (retvar != NULL)
  2530.     {
  2531.     retvar->var_type = type;
  2532.     if (type == VAR_NUMBER)
  2533.         retvar->var_val.var_number = number;
  2534.     else
  2535.     {
  2536.         if (string != NULL)
  2537.         string = vim_strsave(string);
  2538.         retvar->var_val.var_string = string;
  2539.     }
  2540.     }
  2541.  
  2542.     name[len] = cc;
  2543.  
  2544.     return ret;
  2545. }
  2546.  
  2547. /*
  2548.  * Allocate memory for a variable, and make it emtpy (0 or NULL value).
  2549.  */
  2550.     static VAR
  2551. alloc_var()
  2552. {
  2553.     return (VAR)alloc_clear((unsigned)sizeof(var));
  2554. }
  2555.  
  2556. /*
  2557.  * Allocate memory for a variable, and assign a string to it.
  2558.  * The string "s" must have been allocated, it is consumed.
  2559.  * Return NULL for out of memory, the variable otherwise.
  2560.  */
  2561.     static VAR
  2562. alloc_string_var(s)
  2563.     char_u    *s;
  2564. {
  2565.     VAR        retvar;
  2566.  
  2567.     retvar = alloc_var();
  2568.     if (retvar != NULL)
  2569.     {
  2570.     retvar->var_type = VAR_STRING;
  2571.     retvar->var_val.var_string = s;
  2572.     }
  2573.     else
  2574.     vim_free(s);
  2575.     return retvar;
  2576. }
  2577.  
  2578. /*
  2579.  * Free the memory for a variable.
  2580.  */
  2581.     static void
  2582. free_var(varp)
  2583.     VAR        varp;
  2584. {
  2585.     if (varp != NULL)
  2586.     {
  2587.     if (varp->var_type == VAR_STRING)
  2588.         vim_free(varp->var_val.var_string);
  2589.     vim_free(varp->var_name);
  2590.     vim_free(varp);
  2591.     }
  2592. }
  2593.  
  2594. /*
  2595.  * Free the memory for a variable value and set the value to NULL or 0.
  2596.  */
  2597.     static void
  2598. clear_var(varp)
  2599.     VAR        varp;
  2600. {
  2601.     if (varp != NULL)
  2602.     {
  2603.     if (varp->var_type == VAR_STRING)
  2604.     {
  2605.         vim_free(varp->var_val.var_string);
  2606.         varp->var_val.var_string = NULL;
  2607.     }
  2608.     else
  2609.         varp->var_val.var_number = 0;
  2610.     }
  2611. }
  2612.  
  2613. /*
  2614.  * Get the number value of a variable.
  2615.  * If it is a String variable, use vim_str2nr().
  2616.  */
  2617.     static long
  2618. get_var_number(varp)
  2619.     VAR        varp;
  2620. {
  2621.     if (varp->var_type == VAR_NUMBER)
  2622.     return (long)(varp->var_val.var_number);
  2623.     else if (varp->var_val.var_string == NULL)
  2624.     return 0L;
  2625.     else
  2626.     return vim_str2nr(varp->var_val.var_string, NULL, NULL, TRUE, TRUE);
  2627. }
  2628.  
  2629. /*
  2630.  * Get the string value of a variable.
  2631.  * If it is a Number variable, the number is converted into a string.
  2632.  * get_var_string() uses a single, static buffer.  You can only use it once!
  2633.  * get_var_string_buf() uses a given buffer.
  2634.  * If the String variable has never been set, return an empty string.
  2635.  * Never returns NULL;
  2636.  */
  2637.     static char_u *
  2638. get_var_string(varp)
  2639.     VAR        varp;
  2640. {
  2641.     static char_u   mybuf[NUMBUFLEN];
  2642.  
  2643.     return get_var_string_buf(varp, mybuf);
  2644. }
  2645.  
  2646.     static char_u *
  2647. get_var_string_buf(varp, buf)
  2648.     VAR        varp;
  2649.     char_u  *buf;
  2650. {
  2651.     if (varp->var_type == VAR_NUMBER)
  2652.     {
  2653.     sprintf((char *)buf, "%ld", (long)varp->var_val.var_number);
  2654.     return buf;
  2655.     }
  2656.     else if (varp->var_val.var_string == NULL)
  2657.     return (char_u *)"";
  2658.     else
  2659.     return varp->var_val.var_string;
  2660. }
  2661.  
  2662. /*
  2663.  * Find variable "name" in the list of variables.
  2664.  * Return a pointer to it if found, NULL if not found.
  2665.  */
  2666.     static VAR
  2667. find_var(name)
  2668.     char_u    *name;
  2669. {
  2670.     int            i;
  2671.     char_u        *varname;
  2672.     struct growarray    *gap;
  2673.  
  2674.     gap = find_var_ga(name, &varname);
  2675.     if (gap == NULL)
  2676.     return NULL;
  2677.  
  2678.     for (i = gap->ga_len; --i >= 0; )
  2679.     if (VAR_GAP_ENTRY(i, gap).var_name != NULL
  2680.         && STRCMP(VAR_GAP_ENTRY(i, gap).var_name, varname) == 0)
  2681.         break;
  2682.     if (i < 0)
  2683.     return NULL;
  2684.     return &VAR_GAP_ENTRY(i, gap);
  2685. }
  2686.  
  2687. /*
  2688.  * Find the growarray and start of acutal variable name for a variable name.
  2689.  */
  2690.     static struct growarray *
  2691. find_var_ga(name, varname)
  2692.     char_u  *name;
  2693.     char_u  **varname;
  2694. {
  2695.     char_u    *p;
  2696.  
  2697.     p = vim_strchr(name, ':');
  2698.     if (p == NULL)            /* internal variable */
  2699.     {
  2700.     *varname = name;
  2701.     var_init(&variables);
  2702.     return &variables;
  2703.     }
  2704.     *varname = p + 1;
  2705.     if (*name == 'b')            /* local buffer variable */
  2706.     return &curbuf->b_vars;
  2707.     if (*name == 'w')            /* local window variable */
  2708.     return &curwin->w_vars;
  2709.     return NULL;
  2710. }
  2711.  
  2712. /*
  2713.  * Initialize internal variables for use.
  2714.  */
  2715.     void
  2716. var_init(gap)
  2717.     struct growarray *gap;
  2718. {
  2719.     gap->ga_itemsize = sizeof(var);
  2720.     gap->ga_growsize = 4;
  2721. }
  2722.  
  2723. /*
  2724.  * Clean up a list of internal variables.
  2725.  */
  2726.     void
  2727. var_clear(gap)
  2728.     struct growarray *gap;
  2729. {
  2730.     int        i;
  2731.  
  2732.     for (i = gap->ga_len; --i >= 0; )
  2733.     var_free_one(&VAR_GAP_ENTRY(i, gap));
  2734.     ga_clear(gap);
  2735. }
  2736.  
  2737.     static void
  2738. var_free_one(v)
  2739.     VAR        v;
  2740. {
  2741.     vim_free(v->var_name);
  2742.     v->var_name = NULL;
  2743.     if (v->var_type == VAR_STRING)
  2744.     vim_free(v->var_val.var_string);
  2745.     v->var_val.var_string = NULL;
  2746. }
  2747.  
  2748. /*
  2749.  * List the value of one internal variable.
  2750.  */
  2751.     static void
  2752. list_one_var(v, prefix)
  2753.     VAR        v;
  2754.     char_u  *prefix;
  2755. {
  2756.     msg(prefix);
  2757.     msg_puts(v->var_name);
  2758.     msg_putchar(' ');
  2759.     msg_advance(22);
  2760.     if (v->var_type == VAR_NUMBER)
  2761.     msg_putchar('#');
  2762.     else
  2763.     msg_putchar(' ');
  2764.     msg_puts(get_var_string(v));
  2765. }
  2766.  
  2767. /*
  2768.  * Set variable "name" to value in "varp".
  2769.  * If the variable already exists, the value is updated.
  2770.  * Otherwise the variable is created.
  2771.  */
  2772.     static void
  2773. set_var(name, varp)
  2774.     char_u    *name;
  2775.     VAR        varp;
  2776. {
  2777.     int            i;
  2778.     VAR            v;
  2779.     char_u        *varname;
  2780.     struct growarray    *gap;
  2781.  
  2782.     v = find_var(name);
  2783.     if (v != NULL)        /* existing variable, only need to free string */
  2784.     {
  2785.     if (v->var_type == VAR_STRING)
  2786.         vim_free(v->var_val.var_string);
  2787.     }
  2788.     else            /* add a new variable */
  2789.     {
  2790.     gap = find_var_ga(name, &varname);
  2791.     if (gap == NULL)    /* illegal name */
  2792.         return;
  2793.  
  2794.     /* Try to use an empty entry */
  2795.     for (i = gap->ga_len; --i >= 0; )
  2796.         if (VAR_GAP_ENTRY(i, gap).var_name == NULL)
  2797.         break;
  2798.     if (i < 0)        /* need to allocated more room */
  2799.     {
  2800.         if (ga_grow(gap, 1) == FAIL)
  2801.         return;
  2802.         i = gap->ga_len;
  2803.     }
  2804.     v = &VAR_GAP_ENTRY(i, gap);
  2805.     if ((v->var_name = vim_strsave(varname)) == NULL)
  2806.         return;
  2807.     if (i == gap->ga_len)
  2808.     {
  2809.         ++gap->ga_len;
  2810.         --gap->ga_room;
  2811.     }
  2812.     }
  2813.  
  2814.     v->var_type = varp->var_type;
  2815.     if (varp->var_type == VAR_STRING)
  2816.     v->var_val.var_string = vim_strsave(get_var_string(varp));
  2817.     else
  2818.     v->var_val.var_number = varp->var_val.var_number;
  2819. }
  2820.  
  2821. static int echo_attr = 0;   /* attributes used for ":echo" */
  2822.  
  2823. /*
  2824.  * Implementation of
  2825.  * ":echo expr1 .."    print each argument separated with a space, add a
  2826.  *            newline at the end.
  2827.  * ":echon expr1 .."    print each argument plain.
  2828.  */
  2829.     void
  2830. do_echo(eap, echo)
  2831.     EXARG    *eap;
  2832.     int        echo;        /* TRUE for ":echo" command, FALSE for ":echon" */
  2833. {
  2834.     char_u    *arg = eap->arg;
  2835.     var        retvar;
  2836.     char_u    *p;
  2837.     int        first = TRUE;
  2838.  
  2839.     if (eap->skip)
  2840.     ++emsg_off;
  2841.     else if (echo)
  2842.     msg_start();
  2843.     while (*arg != NUL && *arg != '|' && *arg != '\n')
  2844.     {
  2845.     if (eval1(&arg, &retvar) == FAIL)
  2846.         break;
  2847.     if (!eap->skip)
  2848.     {
  2849.         if (arg != eap->arg && echo)
  2850.         msg_puts_attr((char_u *)" ", echo_attr);
  2851.         for (p = get_var_string(&retvar); *p != NUL; ++p)
  2852.         if (*p == '\n' || *p == '\r' || *p == TAB)
  2853.         {
  2854.             if (*p != TAB && first)
  2855.             {
  2856.             /* remove any text still there from the command */
  2857.             msg_clr_eos();
  2858.             first = FALSE;
  2859.             }
  2860.             msg_putchar_attr(*p, echo_attr);
  2861.         }
  2862.         else
  2863.             (void)msg_outtrans_len_attr(p, 1, echo_attr);
  2864.     }
  2865.     clear_var(&retvar);
  2866.     arg = skipwhite(arg);
  2867.     }
  2868.     eap->nextcmd = check_nextcmd(arg);
  2869.  
  2870.     if (eap->skip)
  2871.     --emsg_off;
  2872.     else
  2873.     {
  2874.     /* remove text that may still be there from the command */
  2875.     if (first)
  2876.         msg_clr_eos();
  2877.     if (echo)
  2878.         msg_end();
  2879.     }
  2880. }
  2881.  
  2882. /*
  2883.  * Implementation of ":echohl {name}".
  2884.  */
  2885.     void
  2886. do_echohl(arg)
  2887.     char_u    *arg;
  2888. {
  2889.     int        id;
  2890.  
  2891.     id = syn_name2id(arg);
  2892.     if (id == 0)
  2893.     echo_attr = 0;
  2894.     else
  2895.     echo_attr = syn_id2attr(id);
  2896. }
  2897.  
  2898. /*
  2899.  * Implementation of
  2900.  * ":execute expr1 .."    execute the result of an expression.
  2901.  */
  2902.     void
  2903. do_execute(eap, getline, cookie)
  2904.     EXARG    *eap;
  2905.     char_u    *(*getline) __ARGS((int, void *, int));
  2906.     void    *cookie;        /* argument for getline() */
  2907. {
  2908.     char_u    *arg = eap->arg;
  2909.     var        retvar;
  2910.     int        ret = OK;
  2911.     char_u    *p;
  2912.     struct growarray ga;
  2913.     int        len;
  2914.  
  2915.     ga_init(&ga);
  2916.     ga.ga_itemsize = 1;
  2917.     ga.ga_growsize = 80;
  2918.  
  2919.     if (eap->skip)
  2920.     ++emsg_off;
  2921.     while (*arg != NUL && *arg != '|' && *arg != '\n')
  2922.     {
  2923.     if (eval1(&arg, &retvar) == FAIL)
  2924.     {
  2925.         ret = FAIL;
  2926.         break;
  2927.     }
  2928.  
  2929.     if (!eap->skip)
  2930.     {
  2931.         p = get_var_string(&retvar);
  2932.         len = STRLEN(p);
  2933.         if (ga_grow(&ga, len + 2) == FAIL)
  2934.         {
  2935.         clear_var(&retvar);
  2936.         ret = FAIL;
  2937.         break;
  2938.         }
  2939.         if (ga.ga_len)
  2940.         {
  2941.         ((char_u *)(ga.ga_data))[ga.ga_len++] = ' ';
  2942.         --ga.ga_room;
  2943.         }
  2944.         STRCPY((char_u *)(ga.ga_data) + ga.ga_len, p);
  2945.         ga.ga_room -= len;
  2946.         ga.ga_len += len;
  2947.     }
  2948.  
  2949.     clear_var(&retvar);
  2950.     arg = skipwhite(arg);
  2951.     }
  2952.  
  2953.     if (ret != FAIL && ga.ga_data != NULL)
  2954.     do_cmdline((char_u *)ga.ga_data,
  2955.                  getline, cookie, DOCMD_NOWAIT|DOCMD_VERBOSE);
  2956.  
  2957.     ga_clear(&ga);
  2958.  
  2959.     if (eap->skip)
  2960.     --emsg_off;
  2961.  
  2962.     eap->nextcmd = check_nextcmd(arg);
  2963. }
  2964.  
  2965.     static char_u *
  2966. find_option_end(p)
  2967.     char_u  *p;
  2968. {
  2969.     while (isalnum(*p) || *p == '_')
  2970.     ++p;
  2971.     return p;
  2972. }
  2973.  
  2974. #endif /* WANT_EVAL */
  2975.